package com.xthh._ble;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;

import com.xthh.XTCore;
import com.xthh._enum.HH_EnumDeviceColorType;
import com.xthh._enum.HH_EnumErrorCode;
import com.xthh._enum.HH_EnumOnLineState;
import com.xthh._enum.HH_EnumScanState;
import com.xthh._function.HH_CharUtil;
import com.xthh._function.HH_Logging;
import com.xthh._struct.HH_T_BindDevice;
import com.xthh._struct.HH_T_BleConnectResult;
import com.xthh._struct.HH_T_ScanResult;
import com.xthh._struct.HH_T_SystemParams;
import com.xthh.fastble.BleManager;
import com.xthh.fastble.callback.BleGattCallback;
import com.xthh.fastble.callback.BleMtuChangedCallback;
import com.xthh.fastble.callback.BleScanCallback;
import com.xthh.fastble.data.BleDevice;
import com.xthh.fastble.exception.BleException;
import com.xthh.fastble.scan.BleScanRuleConfig;
import com.xthh._function.HH_SystemUtil;
import com.xt.pro.BLEControlJni;
import com.xt.pro.BleTagInfo;


import java.util.ArrayList;
import java.util.List;

public class HH_BT {
    static final String TAG = "XTHH_BT";
    static public boolean ble_connect_success = false;
    public static List<Integer> globa_list_sub_page_date = new ArrayList<Integer>(); // 补包数据


    public interface ResultCallBackWrite {
        public void callback(boolean writeResult);
    }

    public interface ResultCallBackScanResult {
        public void callback(HH_T_ScanResult scanResult);
    }
    public interface ResultCallBackConnectResult {
        public void callback(HH_T_BleConnectResult bleConnectResult);
    }
    static public void connectBle(HH_T_SystemParams tp, String mac, final ResultCallBackConnectResult resultCallBack){
        HH_Logging.i(TAG, tp, "connectBle");

        BluetoothAdapter bluetoothAdapter =  BleManager.getInstance().getBluetoothAdapter();

        if (mac != null && mac.length() == 12) {
            String s1 = mac.substring(0, 2);
            String s2 = mac.substring(2, 4);
            String s3 = mac.substring(4, 6);
            String s4 = mac.substring(6, 8);
            String s5 = mac.substring(8, 10);
            String s6 = mac.substring(10, 12);
            mac = String.format("%s:%s:%s:%s:%s:%s", s1, s2, s3, s4, s5, s6);
        }

        String sm = HH_SystemUtil.reverseMac(mac);
        BluetoothDevice bluetoothDevice = bluetoothAdapter.getRemoteDevice(sm);
        BleDevice bdCurrent = new BleDevice(bluetoothDevice);

        if (BleManager.getInstance().isConnected(bdCurrent)){
            HH_Logging.i(TAG, tp, "已经连接1");
            BleManager.getInstance().disconnect(bdCurrent);
            HH_SystemUtil.Sleep(2000);
            //resultCallBack.callback(new HH_T_BleConnectResult(true, bdCurrent));
            //return;
            //BleManager.getInstance().disconnect(bdCurrent);
        }
        //HH_T_BleConnectResult bleConnectResult = new HH_T_BleConnectResult(false, null);

        if (bdCurrent != null) {
            HH_Logging.i(TAG, tp, "bdCurrent != null");
            if (!BleManager.getInstance().isConnected(bdCurrent)) {
                HH_Logging.i(TAG, tp, "准备连接");
                BleManager.getInstance().connect(bdCurrent, new BleGattCallback() {
                    @Override
                    public void onStartConnect() {
                        HH_Logging.i(TAG, tp, "开始连接");
                    }

                    @Override
                    public void onConnectFail(BleDevice bleDevice, BleException exception) {
                        HH_Logging.i(TAG, tp, "连接失败");
                        ble_connect_success = false;
                        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_CONNECT_FAIL.ordinal());
                        resultCallBack.callback(new HH_T_BleConnectResult(false, null));
                    }

                    //明天搞这，蓝牙连接
                    @Override
                    public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
                        BleManager.getInstance().setMtu(bleDevice, 512, new BleMtuChangedCallback() {
                            @Override
                            public void onSetMTUFailure(BleException exception) {
                            }

                            @Override
                            public void onMtuChanged(int mtu) {
                            }
                        });

                        HH_Logging.i(TAG, tp, "连接成功");
                        ble_connect_success = true;
                        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_CONNECT_SUCCESS.ordinal());
                        resultCallBack.callback(new HH_T_BleConnectResult(true, bleDevice));
                    }

                    @Override
                    public void onDisConnected(boolean isActiveDisConnected, BleDevice bleDevice, BluetoothGatt gatt, int status) {
                        //SystemUtil.LOG("蓝牙-断开连接：%s", mac);
                        //nCurrentConnectState[0] = 3;
                        HH_Logging.i(TAG, tp, "断开连接");
                        ble_connect_success = false;
                        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, "", 0, HH_EnumErrorCode.BLE_DISCONNECT.ordinal());
                    }
                });
            } else {

                HH_Logging.i(TAG, tp, "已经连接2");
                //SystemUtil.LOG("蓝牙-连接失败：%s", mac);
                //nCurrentConnectState[0] = 1;
                //latch.countDown();
                resultCallBack.callback(new HH_T_BleConnectResult(false, null));
            }
        } else {
            HH_Logging.i(TAG, tp, "构造失败");
            resultCallBack.callback(new HH_T_BleConnectResult(false, null));
        }

     /*   try {
            latch.await();//阻塞异步请求，等待接口回调，同步
        } catch (InterruptedException e) {
        }

        resultCallBack.callback(nCurrentConnectState[0], bdCurrent);*/
    }

    static public void setScanRule() {
        BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder()
                .setServiceUuids(null)                  // 只扫描指定的服务的设备，可选
                .setDeviceName(true, "")   // 只扫描指定广播名的设备，可选
                .setAutoConnect(false)                  // 连接时的autoConnect参数，可选，默认false
                .setScanTimeOut(10000)                  // 扫描超时时间，可选，默认10秒
                .build();
        BleManager.getInstance().initScanRule(scanRuleConfig);
    }

    static public void ScanStop(){
        BleManager.getInstance().cancelScan();
    }

    // 扫描所有的公司的标签
    static public void ScanBegin(HH_T_SystemParams tp, String mac, final ResultCallBackScanResult resultCallBack) {
        BleManager.getInstance().scan(new BleScanCallback() {
            @Override
            public void onScanStarted(boolean success) {
                HH_Logging.i(TAG, tp, "onScanStarted=%b", success);
                if (!success){
                    resultCallBack.callback(new HH_T_ScanResult(HH_EnumScanState.FAIL, null));
                }
            }

            @Override
            public void onLeScan(BleDevice bleDevice) {
                //HH_Logging.i(TAG, tp, "onLeScan");
                super.onLeScan(bleDevice);
            }

            @Override
            public void onScanning(BleDevice bleDevice) {
                byte[] bBleRecord = bleDevice.GetBleRecord();
                if (!BLEControlJni.isXTDevice(bBleRecord, bBleRecord.length)) {
                    return;
                }
                BleTagInfo btInfo = BLEControlJni.GetTagDeviceInfo(bBleRecord, bBleRecord.length);
                if (btInfo.isXT == 2 || btInfo.isXT == 3) {
                    HH_T_BindDevice tbd = SetBindDeviceInfo(btInfo, bleDevice);

                    //String scanResultMac = HH_CharUtil.GetMacFormStr(HH_SystemUtil.reverseMac(bleDevice.getMac()));
                    //HH_Logging.i(TAG, tp, "onScanning=%s,%d", scanResultMac, bleDevice.getRssi());

                    if (mac == null || mac.length() != 12){
                        resultCallBack.callback(new HH_T_ScanResult(HH_EnumScanState.SCANNING, tbd));
                    } else if (mac.length() == 12){
                        if (HH_CharUtil.Strcmp(tbd.getMacRes(), mac, true)){
                            // 只找一个的情况下，就返回一次
                            ScanStop();
                            resultCallBack.callback(new HH_T_ScanResult(HH_EnumScanState.SCANNING, tbd));
                        }
                    }
                }
            }

            @Override
            public void onScanFinished(List<BleDevice> scanResultList) {
                HH_Logging.i(TAG, tp, "onScanFinished");
                resultCallBack.callback(new HH_T_ScanResult(HH_EnumScanState.FINISH, null));
            }
        });
    }

    private static HH_T_BindDevice SetBindDeviceInfo(BleTagInfo btInfo, BleDevice bleDevice) {

        HH_T_BindDevice tbd = new HH_T_BindDevice();

        tbd.setBz("");
        tbd.setProType(btInfo.isXT);
        if (HH_CharUtil.Strcmp(btInfo.deviceColor, "BWRYGBO", true)) {
            tbd.setDeviceColorType(HH_EnumDeviceColorType.N_COLOR_4);
        } else if (HH_CharUtil.Strcmp(btInfo.deviceColor, "BWRY", true)) {
            tbd.setDeviceColorType(HH_EnumDeviceColorType.BLACK_WHITE_RED_YELLOW_3);
        } else if (HH_CharUtil.Strcmp(btInfo.deviceColor, "BWY", true)) {
            tbd.setDeviceColorType(HH_EnumDeviceColorType.BLACK_WHITE_YELLOW_1);
        } else if (HH_CharUtil.Strcmp(btInfo.deviceColor, "BWR", true)) {
            tbd.setDeviceColorType(HH_EnumDeviceColorType.BLACK_WHITE_RED_2);
        } else if (HH_CharUtil.Strcmp(btInfo.deviceColor, "BW", true)) {
            tbd.setDeviceColorType(HH_EnumDeviceColorType.BLACK_WHITE_0);
        } else if (HH_CharUtil.Strcmp(btInfo.deviceColor, "E6", true)) {
            tbd.setDeviceColorType(HH_EnumDeviceColorType.E6_5);
        }
        tbd.setHardwareVer(btInfo.hardwareVer);
        tbd.setName("");
        tbd.setBatteryB(btInfo.battery);
        tbd.setChipType(btInfo.chipType);
        tbd.setSendPower(btInfo.sendPower);
        tbd.setDbm(bleDevice.getRssi());
        tbd.setDeviceName(btInfo.deviceName);
        tbd.setWidth(btInfo.deviceWidth);
        tbd.setHeight(btInfo.deviceHeight);
        tbd.setBwReversal(btInfo.contraryBW == 1);
        tbd.setContraryCOL(btInfo.contraryCOL);
        tbd.setContraryROW(btInfo.contraryROW);
        tbd.setMacRes(HH_CharUtil.GetMacFormStr(HH_SystemUtil.reverseMac(bleDevice.getMac())));
        tbd.setVer(btInfo.softwareVer);
        tbd.setSize(btInfo.size);
        tbd.setIsWithFrontLight(btInfo.withFrontLight);
        tbd.setIsWithLED(btInfo.withLED);
        tbd.setIsWithNewspush(btInfo.withNewspush);
        tbd.setKeyCount(btInfo.keyCount);
        tbd.setOnlineState(HH_EnumOnLineState.DISPLAY_ONLINE);
        tbd.setDeviceNumber(btInfo.deviceNumber);
        tbd.setDeviceType(1);
        return tbd;
    }

    public static int writeBle(HH_T_SystemParams tp, BLE ble, byte[] order) {
        ble.globa_n_WaitAnswerRunning = 1;
        ble.Write(order);
        int nGetTimeout = 0;
        while (ble.globa_n_WaitAnswerRunning == 1){
            HH_SystemUtil.Sleep(2);
            nGetTimeout++;
            if (nGetTimeout > 500 * 20) {
                break;
            }
        }

        HH_Logging.i(TAG, tp, "globa_n_WaitAnswerRunning=%d", ble.globa_n_WaitAnswerRunning);

        // 超时
        if (ble.globa_n_WaitAnswerRunning == 1) {
            return 2;
        }
        // 失败
        if (ble.globa_n_WaitAnswerRunning == 2) {
            return 3;
        }
        // 身份验证失败
        if (ble.globa_n_WaitAnswerRunning == 3) {
            return 4;
        }

        // 应答成功
        return 1;
    }


    public static HH_EnumErrorCode sendDataInfo(HH_T_SystemParams tp,
                                                BLE ble, List<List<Integer>> list,
                                                int type, int pageIntervalTime,
                                                boolean isPrism,
                                                byte []prismParams, int prismParamsLen,
                                                int epdParams) {
        if (list == null)
            return HH_EnumErrorCode.DATA_FAIL;

        // 清空需要补包的序号
        HH_BT.globa_list_sub_page_date = new ArrayList<Integer>();
        for (int i = 0; i < list.size(); i++)
            HH_BT.globa_list_sub_page_date.add(0);

        // 补包次数
        for (int mFailCount = 0; mFailCount < 3; mFailCount++) {
            // 发送数据
            for (int i = 0; i < list.size(); i++) {
                if (!ble_connect_success)
                    return HH_EnumErrorCode.BLE_DISCONNECT;
                if (HH_BT.globa_list_sub_page_date.get(i) < list.size() && HH_BT.globa_list_sub_page_date.get(i) == 0) {
                    byte[] bListToData = HH_CharUtil.ListToByte(list.get(i));
                    SendPicDataToDeviceNoAnswer(ble, BLEControlJni.GetPageDataOrder(1, bListToData, bListToData.length, i, list.size()));
                    //HH_Logging.i(TAG, tp, "发送数据包:%d-%d", i + 1, list.size());
                }

                // 易测试
                HH_SystemUtil.Sleep(pageIntervalTime);

                if (i + 1 == list.size()){
                    HH_SystemUtil.SendMessage(tp, XTCore.MSG_PROGRESS, String.format("%d", pageIntervalTime), 100, 100);
                } else {
                    HH_SystemUtil.SendMessage(tp, XTCore.MSG_PROGRESS, String.format("%d", pageIntervalTime), (i + 1) * 100 / list.size(), 100);}
            }

            byte[] order = null;
            if (isPrism){
                order = BLEControlJni.GetPicUpdateOrderWithParams2(prismParams, prismParamsLen);
            } else {
                HH_Logging.i(TAG, "EPD=%d", epdParams);
                //EPD驱动参数，1字节，（-1时自动设置，-2保持不变，其它手动设置）
                if (epdParams == -1){
                    int battery = HH_SystemUtil.GetBatteryPercentage(tp.getCtx());
                    String model = HH_SystemUtil.getDeviceModel().toLowerCase();
                    HH_Logging.i(TAG, "电量=%d,手机型号=%s", battery, model);

                    if (battery <= 0){
                        // 电量获取异常时用默认的
                        HH_Logging.i(TAG, "BLEControlJni.GetUpdateOrder1=%d", type);
                        order = BLEControlJni.GetUpdateOrder(type, 0);
                    } else {
                        int epdValue = 0;
                        if (model.contains("xiaomi 15 pro")){

                            epdValue = (battery < 60) ? 41 : 37; // 版本23
                            //epdValue = 0x25;  // 250904-康洁要求强制都改为0x25
                            HH_Logging.i(TAG, "BLEControlJni.GetUpdateOrder2-1=%d,0x%02X", 6, epdValue);
                            order = BLEControlJni.GetUpdateOrder(6, epdValue);
                        } else if (model.contains("xiaomi 15s pro")){
                            //epdValue = (battery < 30) ? 0x22 : 0x1F;
                            epdValue = 37;  // 250904-康洁要求强制都改为0x25
                            HH_Logging.i(TAG, "BLEControlJni.GetUpdateOrder2-2=%d,0x%02X", 6, epdValue);
                            order = BLEControlJni.GetUpdateOrder(6, epdValue);
                        } else {
                            HH_Logging.i(TAG, "BLEControlJni.GetUpdateOrder2-3=%d,0x%02X", 6, epdValue);
                            order = BLEControlJni.GetUpdateOrder(type, 0);
                            //epdValue = 0x25;  // 250904-康洁要求强制都改为0x25
                            order = BLEControlJni.GetUpdateOrder(6, epdValue);
                        }
                    }
                } else if (epdParams == -2){
                    HH_Logging.i(TAG, "BLEControlJni.GetUpdateOrder3=%d", type);
                    order = BLEControlJni.GetUpdateOrder(type, 0);
                } else if (epdParams >= 0 && epdParams <= 255){
                    // 手动设置
                    int epdValue = epdParams & 0xFF;
                    HH_Logging.i(TAG, "BLEControlJni.GetUpdateOrder4=%d，0x%02X", 6, epdValue);
                    order = BLEControlJni.GetUpdateOrder(6, epdValue);
                } else {
                    // 默认
                    HH_Logging.i(TAG, "BLEControlJni.GetUpdateOrder5=%d", type);
                    order = BLEControlJni.GetUpdateOrder(type, 0);
                }

            }

            HH_Logging.i(TAG, tp, "发送连接指令:" + HH_CharUtil.ByteToHexStr(order));
            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, HH_CharUtil.ByteToHexStr(order), 0, HH_EnumErrorCode.OTHER_INFO.ordinal());
            HH_EnumErrorCode result = HH_BleCommunicator.SendDataToDevice(tp, ble, order);

            // 这里需要等它返回
            if (result == HH_EnumErrorCode.SUCCESS) {
                HH_Logging.i(TAG, tp, "order-send-success");
                return result;
            } else {
                HH_Logging.i(TAG, tp, "order-send-fail");
                List<Integer> listResult = GetSendFailIndex(list);
                if (listResult.size() == 0) {
                    HH_Logging.i(TAG, tp, "pic send finish");
                    return HH_EnumErrorCode.SUCCESS;
                }
            }
        }

        return HH_EnumErrorCode.FAIL;
    }


    public static HH_EnumErrorCode sendDataInfo_imageStorage(HH_T_SystemParams tp,
                                                             BLE ble,
                                                             List<List<Integer>> list,
                                                             int pageIntervalTime,
                                                             byte[] parameter) {
        if (list == null || parameter == null)
            return HH_EnumErrorCode.DATA_FAIL;

        // 清空需要补包的序号
        HH_BT.globa_list_sub_page_date = new ArrayList<Integer>();
        for (int i = 0; i < list.size(); i++)
            HH_BT.globa_list_sub_page_date.add(0);

        // 补包次数
        for (int mFailCount = 0; mFailCount < 3; mFailCount++) {
            // 发送数据
            for (int i = 0; i < list.size(); i++) {
                if (!ble_connect_success)
                    return HH_EnumErrorCode.BLE_DISCONNECT;
                if (HH_BT.globa_list_sub_page_date.get(i) < list.size() && HH_BT.globa_list_sub_page_date.get(i) == 0) {
                    byte[] bListToData = HH_CharUtil.ListToByte(list.get(i));
                    SendPicDataToDeviceNoAnswer(ble, BLEControlJni.GetPageDataOrder(1, bListToData, bListToData.length, i, list.size()));
                    //HH_Logging.i(TAG, tp, "发送数据包:%d-%d", i + 1, list.size());
                }

                // 易测试
                HH_SystemUtil.Sleep(pageIntervalTime);

                if (i + 1 == list.size()){
                    HH_SystemUtil.SendMessage(tp, XTCore.MSG_PROGRESS, String.format("%d", pageIntervalTime), 100, 100);
                } else {
                    HH_SystemUtil.SendMessage(tp, XTCore.MSG_PROGRESS, String.format("%d", pageIntervalTime), (i + 1) * 100 / list.size(), 100);}
            }

            byte[] order =  BLEControlJni.GetPicUpdateOrderWithParams2(parameter, parameter.length);

            HH_Logging.i(TAG, tp, "发送连接指令:" + HH_CharUtil.ByteToHexStr(order));
            HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, HH_CharUtil.ByteToHexStr(order), 0, HH_EnumErrorCode.OTHER_INFO.ordinal());
            HH_EnumErrorCode result = HH_BleCommunicator.SendDataToDevice(tp, ble, order);

            // 这里需要等它返回
            if (result == HH_EnumErrorCode.SUCCESS) {
                HH_Logging.i(TAG, tp, "order-send-success");
                return result;
            } else {
                HH_Logging.i(TAG, tp, "order-send-fail");
                List<Integer> listResult = GetSendFailIndex(list);
                if (listResult.size() == 0) {
                    HH_Logging.i(TAG, tp, "pic send finish");
                    return HH_EnumErrorCode.SUCCESS;
                }
            }
        }

        return HH_EnumErrorCode.FAIL;
    }


    private static List<Integer> GetSendFailIndex(List<List<Integer>> list) {
        List<Integer> result = new ArrayList<Integer>();

        if (list == null)
            return result;

        String strFail = "";
        int nFailCount = 0;
        if (list.size() != globa_list_sub_page_date.size()) {

        }

        for (int i = 0; i < list.size(); i++) {
            if (i < globa_list_sub_page_date.size() && globa_list_sub_page_date.get(i) == 0) {
                result.add(i);
                strFail += HH_CharUtil.Itoa(i);
                strFail += ",";

                nFailCount++;
            }
        }

        return result;
    }

    private static int SendPicDataToDeviceNoAnswer(BLE ble, byte[] data) {
        if (ble != null && data != null && data.length > 0) {

            // 先放在list里
            List<Integer> listPicData = new ArrayList<Integer>();
            for (int i = 0; i < data.length; i++) {
                int nSetValue = data[i];
                listPicData.add(nSetValue);
            }
            // 固定的244一包
            List<List<Integer>> listPicPageData = HH_SystemUtil.splitList(listPicData, 244);
            for (int i = 0; i < listPicPageData.size(); i++) {
                List<Integer>
                        listOne = listPicPageData.get(i);

                if (listOne.size() > 0) {
                    byte[] array = new byte[listOne.size()];
                    for (int j = 0; j < listOne.size(); j++) {
                        int x = listOne.get(j);
                        array[j] = (byte) x;
                    }

                    ble.Write(array);
                    HH_SystemUtil.Sleep(5);
                }
            }
            return 1;
        } else {
            return 0;
        }
    }

    public static HH_EnumErrorCode sendDataInfo_imageOrder(HH_T_SystemParams tp, BLE ble, byte[] parameter) {
        if (parameter == null)
            return HH_EnumErrorCode.FAIL;

        byte[] order =  BLEControlJni.GetPicUpdateOrderWithParams2(parameter, parameter.length);
        HH_Logging.i(TAG, tp, "发送连接指令:" + HH_CharUtil.ByteToHexStr(order));
        HH_SystemUtil.SendMessage(tp, XTCore.MSG_LOG, HH_CharUtil.ByteToHexStr(order), 0, HH_EnumErrorCode.OTHER_INFO.ordinal());
        HH_EnumErrorCode result = HH_BleCommunicator.SendDataToDevice(tp, ble, order);

        return result;
    }

}
